import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.InputStreamReader;
public class CommonPropertiesContext {
	
	  String [ ]fields=new String[1000];
	  String []methods=new String[1000];
	  String []attributes;
	  String [][]conexpInput;
	  String field=null;
	  String method=null;

	   int methodCount=0;
	  int fieldCount=0;
	  boolean firstClass=true;
	 
 public void extractInfo(String[] fileNames,String []files,int num_files){
    	 try{
    	 	CommonPropertiesParser p=new CommonPropertiesParser();
			p.parseMultipleClasses(files,num_files);
			FileInputStream fstreamForMemberFields = new FileInputStream("InfoFiles/Members1.txt");   
			DataInputStream inForMemberFields = new DataInputStream(fstreamForMemberFields);
			BufferedReader brMemberFields = new BufferedReader(new InputStreamReader(inForMemberFields));
	    
			FileInputStream fstreamForMethodStatement = new FileInputStream("InfoFiles/Methods1.txt");   
			DataInputStream inForMethodStmnt = new DataInputStream(fstreamForMethodStatement);
			BufferedReader brMethodStmnt = new BufferedReader(new InputStreamReader(inForMethodStmnt));
	    
			boolean fexists=false;
		 
			//Storing union of fields in field array
			while ((field=brMemberFields.readLine()) != null){    	
		  	
	    		
	    	 if(firstClass==true){
	    	
         	
	    	    	  
         	   		 if(field.compareTo("End of Class")==0){
         	   			 firstClass=false;
	    			
         	   		 }
         	   		 else{
	    			
         	   			fields[fieldCount]=field;
	    				   
         	   			fieldCount++;	
         	   		}
	    		}   
	    
	    	if(firstClass==false){		   
	    		
	    			fexists=false;
	    			for(int l=0;l<fieldCount;l++){
	    				if(fields[l].compareTo(field)==0){
	    	    	
	    					fexists=true;  
	    	
	    					break;
	    	      
	    				}
	    	    
	    			}
	    		
	    	
	    	
	    
	    	
	    	  if(fexists==false && field.compareTo("End of Class")!=0){	
	    		
	    				fields[fieldCount]=field;

	    				
	    				fieldCount++;
	    			}
	    
	    
	    	}
	    
	    }
	  
	    
	   firstClass=true;
   
	    //storing methods union in methods array
	  
	   while ((method=brMethodStmnt.readLine()) != null){    	
		  	
 		
	    	
        if(firstClass==true){
 	
   	
 	    	  
   	   		 if(method.compareTo("End of class")==0){
   	   			 firstClass=false;
 			
   	   		 }
   	   		 else{
 			
   	   			methods[methodCount]=method;
 				   
   	   			methodCount++;	
   	   		}
 		}   
 
 	if(firstClass==false){		   
 		
 			fexists=false;
 			for(int l=0;l<methodCount;l++){
 				if(methods[l].compareTo(method)==0){
 	    	
 					fexists=true;  
 	
 					break;
 	      
 				}
 	    
 			}
 		
 	
 	
 
 	
 	  if(fexists==false && method.compareTo("End of class")!=0){	
 		
 				methods[methodCount]=method;

 				
 				methodCount++;
 			}
 
 
 	}
 
 }

	   
	   
	    //At this point the fields array contains union of fields
	   // and methods array contains union of methods. Storing them
    //  all in attributes
	   
	   
	  attributes=new String[fieldCount+methodCount];
	  int k;
	  for(k=0; k<fieldCount;k++){
		  
	   attributes[k]=fields[k];
	  
	  }
	  
	   for(int b=0;b<methodCount;b++){
		   
	    attributes[k]=methods[b];
	    k++;
	   
	   }
	  //storing conexp input in matrix		   
	   conexpInput =new String[num_files][fieldCount+methodCount];
	   
	  for(int z=0;z<num_files;z++){
		  
		  for(int v=0;v<fieldCount+methodCount;v++){
			  
		   conexpInput[z][v]="0";
		  }
	  }
	   
	  	int rowField=0;
	  	int rowMethod=0;
	  	int columnField=0;
	  	int columnMethod=0;
	   	
	  	FileInputStream fstreamForMemberFields1 = new FileInputStream("InfoFiles/Members1.txt");   
	    DataInputStream inForMemberFields1 = new DataInputStream(fstreamForMemberFields1);
	    BufferedReader MemberFields = new BufferedReader(new InputStreamReader(inForMemberFields1));
	    
	    FileInputStream fstreamForMethodStatement1 = new FileInputStream("InfoFiles/Methods1.txt");   
	    DataInputStream inForMethodStmnt1 = new DataInputStream(fstreamForMethodStatement1);
	    BufferedReader MethodStmnt = new BufferedReader(new InputStreamReader(inForMethodStmnt1));
	 int g;
	 while ((field=MemberFields.readLine()) != null){    	
		  	
		
		 if(field.compareTo("End of Class")!=0 ){
   	   			 
 	     for(g=0;g<fieldCount;g++){
 	    	 
 	        if(field.compareTo(fields[g])==0){
 	         columnField=g;
 	         conexpInput[rowField][columnField]="1";
 	        }
 	     }
	     }
 	   
	     else{
 	        	
 	       rowField++;
 	        }
 	     
 	     
	 }	 
	     
	 while ((method=MethodStmnt.readLine()) != null){    
	 
	 if(method.compareTo("End of class")!=0){
	
		 
	     for(g=0;g<methodCount;g++){
	    	    	 
	    	if(method.compareTo(methods[g])==0){
	    	          	
	    	        	columnMethod=fieldCount+g;
	    	        	
	    	            conexpInput[rowMethod][columnMethod]="1";
	    	        }
	    	   }
	     
 	 }
	     
  else{
 	 
 	 rowMethod++;
  
  
     }
	   
	 } 
   }catch (Exception e){
   	
	      System.err.println("Error: " + e.getMessage());
	    }

     
 
 
 }



	
public void generateConExpInput(String[] fileNames,String []files,String outputFileName,int num_files) 
	  {
		 
		  try{
			  
			  extractInfo(fileNames,files,num_files);	
			  
						  
			  BufferedWriter output;				
			  output = new BufferedWriter(new FileWriter(outputFileName));
			  
		   	 
		   
 //writing field and method names in file
		   
		 output.write(";");
		 for(int y=0;y<fieldCount+methodCount;y++){
			   output.write(attributes[y]);    	
			   output.write(";");
		   } 		
		   
		   
		   output.newLine();
		   output.newLine();
		   
	//writing binary matrix to file	  
		   
		   for(int z=0;z<num_files;z++){
				  
				output.write(fileNames[z]);  
			   for(int v=0;v<fieldCount+methodCount;v++){
				   output.write(";");
				  output.write(conexpInput[z][v]);
				   
			     }
			     output.write(";");
			     output.newLine();
		   
		   }
		   
		    output.close(); 
		     
		   
		  }catch (Exception e){
		    	
		      System.err.println("Error: " + e.getMessage());
		    }
		    


      }

 
    
	  
	  public void generateGaliciaInput(String[] fileNames,String []files,String outputFileName,int num_files) 
	  {
		 
		  try{
			  
			  
			  extractInfo(fileNames,files,num_files);	
			 
			  BufferedWriter output;				
			  output = new BufferedWriter(new FileWriter(outputFileName));
			  output.write("[Relational Context]\rMultiClass\r[Binary Relation]\rMultiClass\r");
		   
			  //writing class names
		   
		   for(int z=0;z<num_files;z++){
				  
				output.write(fileNames[z]); 
		        output.write(" | ");
		   }
		   
		   output.write("\r");
		   //writing attributes names
		   
		   for(int y=0;y<fieldCount+methodCount;y++){
			   output.write(attributes[y]);    	
			   output.write(" | ");
		   } 		
		   
		   
		   output.write("\r");
		   
		   //writing binary matrix to file	  
		   
		   for(int z=0;z<num_files;z++){
			
			   for(int v=0;v<fieldCount+methodCount;v++){
				 
				  output.write(conexpInput[z][v]);
				  output.write(" ");
			     }
			   
			   output.write("\r");
		   }
		   
		   output.write("[END Relational Context]");
		
		   output.write("\r");
		   
		   output.close(); 
		     
		   
		  }catch (Exception e){
		    	
		      System.err.println("Error: " + e.getMessage());
		    }
		    


      }

 
   
}
